#ifndef _CHATHANDLER_H
#define _CHATHANDLER_H

class Player;
class ChatHandler;
class ChatCommand;

enum ChatMsg
{
	CHAT_MSG_ADDON									= -1,
	CHAT_MSG_SYSTEM                                 = 0,
	CHAT_MSG_SAY									= 1,
	CHAT_MSG_PARTY									= 2,
	CHAT_MSG_RAID									= 3,
	CHAT_MSG_GUILD									= 4,
	CHAT_MSG_OFFICER								= 5,
	CHAT_MSG_YELL									= 6,
	CHAT_MSG_WHISPER								= 7,
	CHAT_MSG_WHISPER_MOB							= 8,
	CHAT_MSG_WHISPER_INFORM							= 9,
	CHAT_MSG_EMOTE									= 10,
	CHAT_MSG_TEXT_EMOTE								= 11,
	CHAT_MSG_MONSTER_SAY							= 12,
	CHAT_MSG_MONSTER_PARTY							= 13,
	CHAT_MSG_MONSTER_YELL							= 14,
	CHAT_MSG_MONSTER_WHISPER						= 15,
	CHAT_MSG_MONSTER_EMOTE							= 16,
	CHAT_MSG_CHANNEL								= 17,
	CHAT_MSG_CHANNEL_JOIN							= 18,
	CHAT_MSG_CHANNEL_LEAVE							= 19,
	CHAT_MSG_CHANNEL_LIST							= 20,
	CHAT_MSG_CHANNEL_NOTICE							= 21,
	CHAT_MSG_CHANNEL_NOTICE_USER					= 22,
	CHAT_MSG_AFK									= 23,
	CHAT_MSG_DND									= 24,
	CHAT_MSG_IGNORED								= 25,
	CHAT_MSG_SKILL									= 26,
	CHAT_MSG_LOOT									= 27,
    CHAT_MSG_MONEY                                  = 28,
    CHAT_MSG_OPENING                                = 29,
    CHAT_MSG_TRADESKILLS                            = 30,
    CHAT_MSG_PET_INFO                               = 31,
    CHAT_MSG_COMBAT_MISC_INFO                       = 32,
    CHAT_MSG_COMBAT_XP_GAIN                         = 33,
    CHAT_MSG_COMBAT_HONOR_GAIN                      = 34,
    CHAT_MSG_COMBAT_FACTION_CHANGE                  = 35,
	CHAT_MSG_BG_EVENT_NEUTRAL						= 36,
	CHAT_MSG_BG_EVENT_ALLIANCE						= 37,
	CHAT_MSG_BG_EVENT_HORDE							= 38,
	CHAT_MSG_RAID_LEADER							= 39,
	CHAT_MSG_RAID_WARNING							= 40,
	CHAT_MSG_RAID_WARNING_WIDESCREEN				= 41,
    CHAT_MSG_RAID_BOSS_EMOTE                        = 42,
	CHAT_MSG_FILTERED								= 43,
	CHAT_MSG_BATTLEGROUND							= 44,
	CHAT_MSG_BATTLEGROUND_LEADER					= 45,
	CHAT_MSG_RESTRICTED								= 46,
	CHAT_MSG_ACHIEVEMENT							= 47,
    CHAT_MSG_GUILD_ACHIEVEMENT						= 48,
};

struct ChatMessage
{
	ui32 type, language;
	Player* sender;
	char message[255];
};

class DLL_EXPORT ChatCommandTable
{
	friend class ChatHandler;
	set<ChatCommand*> m_commands;
	ChatCommand* GetCommand(char* cmdtext);
	void InsertCmd(bool (ChatHandler::*)(Player*, char*), char* name, char* helptext, char lvl, ChatCommandTable* subcommands = 0);
	void InsertCmd(ChatCommand* chatcmd) { m_commands.insert(chatcmd); }
	void PrintSubcmds(Player* sender);
};

class DLL_EXPORT ChatCommand
{
	typedef bool (ChatHandler::*chatproc)(Player*, char*);
public:
	char* InternalName;
	char* HelpText;
	char RequiredLevel;
	chatproc ChatProc;
	ChatCommandTable* subcommands;
	void PrintHelpText(Player* target);
};

class DLL_EXPORT ChatHandler : public Single<ChatHandler>
{
	set<ChatCommandTable*> CommandTableStorage;
	bool ParseMessage(ChatMessage& cmsg);
	ChatCommand* FindRegularCommand(char* command);
	void InitCmds();
	void HandleChatCommand(ChatCommand* cmd, Player* sender, char* args);
public:
	ChatHandler();
	void HandleChatMessage(ChatMessage& cmsg, RealmPacket* remaining);
	bool BuildChatPacket(char* message, ui32 senderguid, ui32 type, ui32 language, RealmPacket* out);
	void BuildSystemPacket(char* message, RealmPacket* out);

protected:
	//	Insert your own Commandfunctions here!
	bool HandleWorldPortCmd(Player*, char*);
	bool HandleNPCSpawnCmd(Player*, char*);
	bool HandleNPCInfoCmd(Player*, char*);
	bool HandleNPCDeleteCmd(Player*, char*);
	bool HandleNPCFlagCmd(Player*, char*);
	bool HandleNPCFactionCmd(Player*, char*);
	bool HandleNPCEmoteCmd(Player*, char*);
	bool HandleNPCMovespCmd(Player*, char*);
	bool HandleWayPointAdd(Player*, char*);
	bool HandleWayPointActivate(Player*, char*);
	bool HandleDebugMove(Player*, char*);
	bool HandleModifySpeed(Player*, char*);
	bool HandleModifyMoney(Player*, char*);
	bool HandleCheatFly(Player*, char*);
	bool HandleRecallAdd(Player*, char*);
	bool HandleRecallPort(Player*, char*);
	bool HandleAnnounce(Player*, char*);
	bool HandleNpcPower(Player*, char*);
	bool HandleGameObjectReloadTele(Player*, char*);
	bool HandleGameObjectSelect(Player*, char*);
	bool HandleGameObjectFlags(Player*, char*);
	bool HandleGameObjectState(Player*, char*);
	bool HandleGameObjectByte2(Player*, char*);
	bool HandleGameObjectByte3(Player*, char*);
};

#define sChatHandler ChatHandler::getSingle()

#endif